const { ipcMain, dialog, app } = require("electron");
const path = require("node:path");
const fs = require("fs");
const Datastore = require("node-persist");

global.RootKey = 'LOCAL-DATA-YUTIAN-PACS'

//默认数据格式及默认值
const DefaultData = {
    hospitalName: undefined,
    filePath: undefined,
    dataPath: path.join('C:', 'YuTianDateBase'),
}

//缓存所在文件夹
const CacheDirPath = path.join(
    process.env.LOCALAPPDATA || process.env.PROGRAMFILES,
    "YuTian",
    "YuTianPacs",
    "data"
);

//初始化路径
const initPath = () => {
    return new Promise((resolve, reject) => {
        fs.access(CacheDirPath, fs.constants.F_OK, (error) => {
            if (error) {
                //文件夹不存在
                fs.mkdir(CacheDirPath, { recursive: true }, (mkdirErr) => {
                    if (mkdirErr) {
                        reject("创建缓存文件夹失败:" + mkdirErr)
                        return;
                    }
                    resolve()
                });
                return
            }
            resolve()
        })
    })
}

//初始化默认数据
const doDefaultValue = async () => {
    const storageData = await Datastore.get(RootKey) ?? {};
    const finalData = Object.assign(DefaultData, storageData)
    await Datastore.set(RootKey, finalData);
}

//保存数据
const saveData = async (data) => {
    const storageData = await Datastore.get(RootKey);
    let finalData = undefined
    finalData = Object.assign(storageData, data)
    await Datastore.set(RootKey, finalData);
}

//获取数据
const getData = async (key) => {
    const storageData = await Datastore.get(RootKey);
    if (key) {
        return storageData[key]
    }
    return storageData
}

const clearStorage = () => {
    try {
        fs.rmdirSync(CacheDirPath, { recursive: true });
    } catch (err) {
        console.error('Storage文件夹删除失败：', err);
    }
}

module.exports = {
    async initStorage() {
        await initPath()
        //开始初始化
        await Datastore.init({
            dir: CacheDirPath
        });
        //初始化默认数据
        await doDefaultValue()
        //添加IPC监听
        ipcMain.on("STORAGE-SAVE", async function (event, arg) {
            //关闭数据库的方法
            const closeDB = () => {
                return new Promise(resolve => {
                    db.close(() => {
                        resolve()
                    })
                })
            }
            const { data } = arg;
            //判断数据目录是否发生改变，如果改变，需要移动数据文件
            const oldDataPath = await getData('dataPath')
            if (oldDataPath != data.dataPath) {
                //发生改变
                const result = await dialog.showMessageBoxSync({
                    title: '数据转移提示',
                    message: '数据转移有风险，您确定要执行数据转移吗？\n转移中请勿关闭软件，成功后将自动重启软件',
                    buttons: ['确定', '取消'],
                    cancelId: 1
                })
                if (result === 1) {
                    event.returnValue = { cancel: true }
                    return
                }
                //制定关闭软件后的任务
                try {
                    //开始操作文件夹
                    //1.确认目标文件夹是否存在，如不存在则创建
                    if (!fs.existsSync(data.dataPath)) {
                        fs.mkdirSync(data.dataPath, { recursive: true });
                    }
                    const sourcePath = path.join(oldDataPath, 'main.db')
                    const destinationPath = path.join(data.dataPath, 'main.db')
                    if (fs.existsSync(destinationPath)) {
                        throw new Error('new filePath exist')
                    }
                    fs.copyFileSync(sourcePath, destinationPath);
                    await saveData(data);
                    console.log('文件已复制');
                    await closeDB()
                    // fs.unlinkSync(sourcePath);
                    fs.rmdirSync(oldDataPath, { recursive: true });
                    console.log('原文件已删除');
                } catch (e) {
                    console.log('错误', e)
                    dialog.showErrorBox('错误', '设置应用失败，请重新配置。\n' + e)
                }
                app.relaunch()
                app.exit()
            } else {
                await saveData(data);
            }
            event.returnValue = {}
        });
        ipcMain.on("STORAGE-GET", async function (event, arg) {
            const { key } = arg ?? {};
            const value = await getData(key)
            event.returnValue = { key, value }
        });
    },
    saveData,
    getData,
    clearStorage
}

